#ifndef   	PARSER_H
#define   	PARSER_H

#include <iostream>
#include <istream>
#include <string>
#include <list>
#include <stack>
#include <sstream>
#include <fstream>

namespace eg {

using namespace std;

typedef unsigned long pos_type;

// Syntax tree node representation
class ast {

public:

	ast(string description = "") :
		desc(description) {
	}
	~ast();

	void push_child(ast * child);
	ast * get_child(int index);

	bool is_a_leaf() {
		return childs.empty();
	}

	virtual void do_action() {
	}
	;

	virtual string to_string();

	int get_begin_pos() const {
		return begin_pos;
	}

	void set_begin_pos(int bp) {
		begin_pos = bp;
	}

	int get_end_pos() const {
		return end_pos;
	}

	void set_end_pos(int ep) {
		end_pos = ep;
	}

	int get_new_line() const {
		return acum_new_line;
	}

	void set_new_line(int nl) {
		acum_new_line = nl;
	}

	list<ast *> get_childs() {
		return childs;
	}

protected:

	string desc;
	list<ast *> childs; // child nodes
	int begin_pos;
	int end_pos;
	int acum_new_line;

};

typedef stack<ast *> semantic_stack;

class rule; // forward declaration (rule defined below)

class parser;

class blanks;

// Base (abstract) class representing a expression grammar parser
class context {
public:

	context(istream & i) :
		input(i), parcial_nl_counter(0),acum_nl_counter(0) {
	}
	~context() {
	}
	;
	istream & input; 						// input stream to parse
	semantic_stack s;						// ast stack
	parser * skip_parser;					// blank skiper parser
	int last_char_pos;						// current position of char in treatment
	int parcial_nl_counter;					// localnew line counter
	int acum_nl_counter;					// total new line counter
	int error_mode;							// if true there is an error to report
	int error_mode_by_mistake;				// if true error parse is parsing a look ahead
	int brake_error_parser;					// if true, look ahead was found in error parser
	parser * disable_parser();				// disable skip parser
	void enable_parser(parser * aux_parser);// enable skip parser
	stack<parser *> error_rule_stack;		// error rule stack

};
class parser {

public:

	parser() {
	}
	virtual ~parser() {
	}

	bool is_left_recursive() {
		return left_recursive(static_cast<parser *> (this));
	}

	// Start parsing. Return an non empty abstract syntax tree on sucess, otherwise 0 (null)
	ast * do_parsing(istream & input, parser * skip_parser = 0);

	// Usefull functions to create parsers.

	parser & a_char(char c); // a parser for a given char ('c')
	parser & some_char(); // any character parser (.)
	parser & a_word(string s); // a parser for a given string ("s")
	parser & in(string s); // a parser for a character class represented by s ([s])
	parser & in(char from, char until); // a parser for character range ([from-until])
	parser & not_a(parser & p); // not predicate (!E)
	parser & follows(parser & p); // and predicate (&E)
	parser & one_or_more(parser & p); // one or more (E+)
	//parser & operator*(parser & p);  // zero or more (E*)
	parser & zero_or_more(parser & p);
	parser & maybe(parser & p); // zero or one (E?)
	parser & end_of_input(); // obvious
	parser & error(char rec_point, char look_ahead); // an error parser for a recuperation point rec_point


	// concatenation operator (sequence)
	virtual parser & operator+(parser & p);

	// ordered choice operator
	virtual parser & operator|(parser & p);

	// real parsing action
	virtual bool parse(bool gen_ast = true) = 0;

	// print the grammar represented by this parser
	virtual string to_string() {
		return "";
	}

	virtual bool is_a_rule() {
		return false;
	}

	virtual string parser_name() {
		return "";
	}


	virtual bool left_recursive(parser * from) {
		return this == from;
	}
	stack<parser *> error_parsers_stack;// error parser stack for each rule

protected:

	static context * the_context; // singleton (shared context)

	// auxiliary routines
	bool accept(string node_desc, int begin_pos, int childs = 0);
	bool reject(pos_type back_to, int childs_to_free = 0);

}; // class parser


}

#endif 	    
